from django.core.exceptions import ValidationError
from django.db import models

# Create your models here.
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.hashers import make_password, check_password

# 可以通过 命令 python  manage.py createsuperuser 来创建超级管理员
# 就是在这User表中添加记录
from django.db.models import Q


class User(AbstractUser):
    id = models.BigAutoField(primary_key=True)
    # 覆盖原有id定义，使用BigAutoField将会更大，不用考虑上限问题

    # 用户类型
    # 1： 超管 | 2： 普通管理员  | 3： 普通用户
    usertype = models.PositiveIntegerField(choices=[(1, '超级管理员'), (2, '管理员'), (3, '普通用户')], default=3)

    # 真实姓名
    realname = models.CharField(max_length=30, db_index=True, verbose_name="真实姓名")

    # 备注描述
    desc = models.CharField(max_length=500, null=True, blank=True)
    mobile = models.CharField(max_length=30, blank=True, null=True, verbose_name='手机号', unique=True)

    REQUIRED_FIELDS = ['usertype', 'realname']

    def __str__(self):
        return self.realname


class UserRight(models.Model):
    user = models.ForeignKey(to=User, on_delete=models.CASCADE)
    right = models.ForeignKey(to='UserRightConfig', on_delete=models.CASCADE)
    end_time = models.DateTimeField(null=True, blank=True, default=None)
    update_time = models.DateTimeField(auto_now=True)


class UserRightConfig(models.Model):
    category = models.SmallIntegerField(choices=((1, '免费版'), (2, '收费版'), (3, '其他')), default=1)
    title = models.CharField(max_length=20)
    price = models.DecimalField(max_digits=6, decimal_places=2)
    project_num = models.PositiveIntegerField()
    project_member = models.PositiveIntegerField()
    project_space = models.PositiveIntegerField()
    single_file_space = models.PositiveIntegerField()
    create_time = models.DateTimeField(auto_now_add=True)


class RightOrder(models.Model):
    order_num = models.CharField(max_length=64, unique=True)  # 唯一索引
    order_by_user = models.ForeignKey(to=User, on_delete=models.CASCADE)
    order_right = models.ForeignKey(to=UserRightConfig, on_delete=models.SET_DEFAULT, default=0)
    order_status = models.SmallIntegerField(choices=((1, '待支付'), (2, '已支付'), (3, '已关闭')))
    order_price = models.DecimalField(max_digits=7, decimal_places=2)
    order_quantity = models.IntegerField()
    create_time = models.DateTimeField(auto_now_add=True)


class Project(models.Model):
    COLOR_CHOICES = (
        (1, "#56b8eb"),  # 56b8eb
        (2, "#f28033"),  # f28033
        (3, "#ebc656"),  # ebc656
        (4, "#a2d148"),  # a2d148
        (5, "#20BFA4"),  # #20BFA4
        (6, "#7461c2"),  # 7461c2,
        (7, "#20bfa3"),  # 20bfa3,
    )
    project_title = models.CharField(max_length=20, verbose_name="项目标题")
    project_desc = models.TextField(verbose_name="项目描述")
    project_color = models.SmallIntegerField(verbose_name='项目颜色', choices=COLOR_CHOICES, default=1)
    # project_star = models.BooleanField(default=False)
    creator = models.ForeignKey(to=User, on_delete=models.SET_NULL, null=True, blank=True)
    workers_num = models.IntegerField(default=1)
    used_space = models.DecimalField(default=0, max_digits=10, decimal_places=2)
    create_time = models.DateTimeField(auto_now_add=True)
    bucket = models.CharField(max_length=128, verbose_name='cos桶名称')
    region = models.CharField(max_length=32, verbose_name="cos地区")

    class Meta:
        unique_together = ("project_title", "creator")

    def __str__(self):
        return self.project_title


class ProjectRelation(models.Model):
    project = models.ForeignKey(to=Project, on_delete=models.CASCADE)
    user = models.ForeignKey(to=User, on_delete=models.CASCADE)
    star = models.BooleanField(default=False)
    create_datetime = models.DateTimeField(verbose_name='加入时间', auto_now_add=True)


class Wiki(models.Model):
    project = models.ForeignKey(to=Project, on_delete=models.CASCADE, verbose_name='项目')
    title = models.CharField(max_length=32, verbose_name='标题')
    content = models.TextField(verbose_name='内容')
    parent = models.ForeignKey(to='self', on_delete=models.CASCADE, null=True, blank=True, related_name='child',
                               verbose_name='上级文章')
    depth = models.SmallIntegerField(default=0)

    def __str__(self):
        return self.title


class FileRepository(models.Model):
    """ 文件库 """
    project = models.ForeignKey(verbose_name='项目', to='Project', on_delete=models.CASCADE)
    file_type_choices = (
        (1, '文件'),
        (2, '文件夹')
    )
    file_type = models.SmallIntegerField(verbose_name='类型', choices=file_type_choices)
    name = models.CharField(verbose_name='文件夹名称', max_length=32, help_text="文件/文件夹名")
    key = models.CharField(verbose_name='文件储存在COS中的KEY', max_length=128, null=True, blank=True, default=None)

    # int类型最大表示的数据
    file_size = models.BigIntegerField(verbose_name='文件大小', null=True, blank=True, help_text='字节', default=None)

    file_path = models.CharField(verbose_name='文件路径', max_length=255, null=True,
                                 blank=True, default=None)  # https://桶.cos.ap-chengdu/....

    parent = models.ForeignKey(verbose_name='父级目录', to='self', related_name='child', null=True, blank=True,
                               on_delete=models.CASCADE)

    update_user = models.ForeignKey(verbose_name='最近更新者', to='User', on_delete=models.CASCADE)
    update_datetime = models.DateTimeField(verbose_name='更新时间', auto_now=True)

    class Meta:
        # unique_together = ("name", "file_type", 'parent')
        constraints = [
            models.UniqueConstraint(fields=("name", "file_type", 'parent', 'project'), name='with_parent_unique'),
            models.UniqueConstraint(fields=("name", "file_type", 'project'), condition=Q(parent=None),
                                    name='without_parent_unique')
        ]


class Issues(models.Model):
    """ 问题 """
    project = models.ForeignKey(verbose_name='项目', to='Project', on_delete=models.CASCADE)
    issues_type = models.ForeignKey(verbose_name='问题类型', to='IssuesType', on_delete=models.CASCADE)
    module = models.ForeignKey(verbose_name='模块', to='Module', null=True, blank=True, on_delete=models.CASCADE)

    subject = models.CharField(verbose_name='主题', max_length=80)
    desc = models.TextField(verbose_name='问题描述')
    priority_choices = (
        ("danger", "高"),
        ("warning", "中"),
        ("success", "低"),
    )
    priority = models.CharField(verbose_name='优先级', max_length=12, choices=priority_choices, default='danger')

    # 新建、处理中、已解决、已忽略、待反馈、已关闭、重新打开
    status_choices = (
        (1, '新建'),
        (2, '处理中'),
        (3, '已解决'),
        (4, '已忽略'),
        (5, '待反馈'),
        (6, '已关闭'),
        (7, '重新打开'),
    )
    status = models.SmallIntegerField(verbose_name='状态', choices=status_choices, default=1)

    assign = models.ForeignKey(verbose_name='指派', to='User', related_name='task', null=True, blank=True,
                               on_delete=models.CASCADE)
    attention = models.ManyToManyField(verbose_name='关注者', to='User', related_name='observe', blank=True)

    start_date = models.DateField(verbose_name='开始时间', null=True, blank=True)
    end_date = models.DateField(verbose_name='结束时间', null=True, blank=True)
    mode_choices = (
        (1, '公开模式'),
        (2, '隐私模式'),
    )
    mode = models.SmallIntegerField(verbose_name='模式', choices=mode_choices, default=1)

    parent = models.ForeignKey(verbose_name='父问题', to='self', related_name='child', null=True, blank=True,
                               on_delete=models.SET_NULL)

    creator = models.ForeignKey(verbose_name='创建者', to='User', related_name='create_problems', on_delete=models.CASCADE)

    create_datetime = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    latest_update_datetime = models.DateTimeField(verbose_name='最后更新时间', auto_now=True)

    def __str__(self):
        return self.subject


class Module(models.Model):
    """ 模块（里程碑）"""
    project = models.ForeignKey(verbose_name='项目', to='Project', on_delete=models.CASCADE)
    title = models.CharField(verbose_name='模块名称', max_length=32)
    attachment = models.OneToOneField(verbose_name="附件", to=FileRepository, on_delete=models.SET_NULL, null=True,
                                      blank=True)

    def __str__(self):
        return self.title


class IssuesType(models.Model):
    """ 问题类型 例如：任务、功能、Bug """

    PROJECT_INIT_LIST = ["任务", '功能', 'Bug']

    title = models.CharField(verbose_name='类型名称', max_length=32)
    project = models.ForeignKey(verbose_name='项目', to='Project', on_delete=models.CASCADE)

    def __str__(self):
        return self.title


class IssuesReply(models.Model):
    """ 问题回复"""

    reply_type_choices = (
        (1, '修改记录'),
        (2, '回复消息')
    )
    reply_type = models.IntegerField(verbose_name='类型', choices=reply_type_choices)

    issues = models.ForeignKey(verbose_name='问题', to='Issues', on_delete=models.CASCADE)
    content = models.TextField(verbose_name='描述')
    creator = models.ForeignKey(verbose_name='创建者', to='User', related_name='create_reply', on_delete=models.CASCADE)
    create_datetime = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)

    reply = models.ForeignKey(verbose_name='父级回复', to='self', null=True, blank=True, on_delete=models.CASCADE)


class ProjectInvite(models.Model):
    """ 项目邀请码 """
    project = models.ForeignKey(verbose_name='项目', to='Project', on_delete=models.CASCADE)
    code = models.CharField(verbose_name='邀请码', max_length=64, unique=True)
    count = models.PositiveIntegerField(verbose_name='限制数量', null=True, blank=True, help_text='空表示无数量限制')
    use_count = models.PositiveIntegerField(verbose_name='已邀请数量', default=0)
    period_choices = (
        (30, '30分钟'),
        (60, '1小时'),
        (300, '5小时'),
        (1440, '24小时'),
    )
    period = models.IntegerField(verbose_name='有效期', choices=period_choices, default=1440)
    create_datetime = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    creator = models.ForeignKey(verbose_name='创建者', to='User', related_name='create_invite', on_delete=models.CASCADE)
